
// es6写法
class LazyMan {
  constructor(arg) {
    this.tasks = [];
    const task = () => {
      console.log(`Hi! This is ${arg}!`);
      this._next();
    };
    this.tasks.push(task);
    setTimeout(() => {
      this._next();
    }, 0);
  }
  _next = () => {
    const task = this.tasks.shift();
    task?.();
  };
  eat = (arg) => {
    const task = () => {
      console.log(`Eat ${arg}~`);
      this._next();
    };
    this.tasks.push(task);
    return this;
  };
  sleep = (time) => {
    this._sleep(time, false);
    return this;
  };
  sleepFirst = (time) => {
    this._sleep(time, true);
    return this;
  };
  _sleep = (time, first) => {
    const task = () => {
      setTimeout(() => {
        console.log(`Wake up after ${time}`);
        this._next();
      }, time * 1000);
    };
    if (first) {
      this.tasks.unshift(task);
    } else {
      this.tasks.push(task);
    }
  };
}


// es5写法
/* function LazyMan(name) {
  this.tasks = [];
  var task = function() {
    console.log(`Hi! This is ${name}!`);
    this._next();
  }.bind(this);
  this.tasks.push(task);
  setTimeout(this._next.bind(this), 0)
}

LazyMan.prototype._next = function() {
  var task = this.tasks.shift();
  task && task();
}

LazyMan.prototype.eat = function(arg) {
  var task = function() {
    console.log(`Eat ${arg}~`);
    this._next();
  }.bind(this);
  this.tasks.push(task);
  return this;
}

LazyMan.prototype._sleep = function(time, first) {
  var self = this;
  var task = function() {
    setTimeout(function() {
      console.log(`Wake up after ${time}`);
      self._next();
    }, time * 1000);
  }.bind(this);
  if(first) {
    this.tasks.unshift(task);
  } else {
    this.tasks.push(task);
  }
}

LazyMan.prototype.sleep = function(time) {
  this._sleep(time, false);
  return this;
}

LazyMan.prototype.sleepFirst = function(time) {
  this._sleep(time, true);
  return this;
} */

/* 
//  利用异步的宏/微任务
class LazyMan {
  constructor(name) {
    this.name = name;
    setTimeout(() => {
      console.log("Hi! This is " + name);
    }, 0);
  }

  sleep(seconds) {
    const delay = seconds * 1000;
    const time = Date.now();
    while (Date.now() - time < delay) {
      // hu lu lu ~~
    }
    setTimeout(() => {
      console.log("wake up after " + seconds);
    }, 0);
    return this;
  }

  eat(something) {
    setTimeout(() => {
      console.log("eat " + something);
    }, 0);
    return this;
  }

  sleepFirst(seconds) {
    new Promise((resolve) => {
      const delay = seconds * 1000;
      const time = Date.now();
      while (Date.now() - time < delay) {
        // hu lu lu ~~
      }
      resolve();
    }).then(() => {
      console.log("wake up after " + seconds);
    });
    return this;
  }
} */


// new LazyMan('Hank');
// Hi! This is Hank!

// new LazyMan('Hank').sleep(10).eat('dinner');
// Hi! This is Hank!
//等待10秒..
// Wake up after 10
// Eat dinner~

// new LazyMan('Hank').eat('dinner').eat('supper');
// Hi This is Hank!
// Eat dinner~
// Eat supper~

// new LazyMan('Hank').eat('supper').sleepFirst(5);
//等待5秒
// Wake up after 5
// Hi This is Hank!
// Eat supper
